<template>
  <div class="form-detail">
    <!-- <el-tabs v-model="activeName" v-if="wpsList.length > 1" type="card" class="demo-tabs" @tab-change="handleClick">
      <el-tab-pane v-for="(item, index) in wpsList" :label="(item as any).name" :name="index" :key="index"></el-tab-pane>
    </el-tabs> -->
    <!-- 左侧公文区域 -->
    <div :id="wps_wordId" ref="wps_word" :style="iframeStyle"></div>
    <!-- 左侧公文区域结束 -->
  </div>
</template>

<script lang="ts">
import { generateId } from "@/utils/util";
// import CreatWpsView from "@/utils/wpsOffice/creatSdk";
import { getWpsUrl, EventType } from "@/api/document/wps"

export default {
  name: "ZHLX-wpsWord",
  props: {
    wpsList: {
      type: Array,
      default: () => [],
    },
    config: {
      type: Object,
      default: () => { },
    },
  },
  inject: {
    parameter: {
      type: Object,
      default: () => {
        return null;
      },
    },
    wpsFunction: {
      type: Object,
      default: () => {
        return {};
      },
    },
    getWpsData: {
      type: Function,
      default: () => {
        return null;
      },
    },
    flowThis: {
      type: Object,
      default: () => { }
    },
    type: {
      type: String,
      default: 'edit'
    },
    getGlobalDsv: {
      type: Object,
      default: () => {}
    },
  },
  data() {
    return {
      wpsHeight: "100%",
      instance: undefined,
      timeClear: null,
      activeName: 0,
      currentId: null
    };
  },
  beforeDestroy() {
    clearInterval(this.timeClear);
    window.removeEventListener("resize", () => { });
    this.instance.ApiEvent.RemoveApiEventListener("WindowSelectionChange")
  },
  mounted() {
    if (document.getElementById('WPSSdk') == null) {
      this.creatWpsSdk();
    }
    this.setWpsHeight();
    //  = `${wpsClientHeight}px`;
    if (this.wpsList.length > 0) {
      this.initWpsSdk(this.wpsList[0].id, this.wpsList[0].fileType)
    }
    window.addEventListener('resize', () => {
      this.setWpsHeight();
    })
  },
  watch: {
    currentWpsFile: {
      deep: true,
      handler(val, oldVal) {
        this.initWpsSdk(val.id, val.fileType)
      }
    }
  },
  computed: {
    iframeStyle() {
      return {
        height: this.wpsHeight,
        border: "medium none",
        width: "100%",
        display: "block",
      };
    },
    wpsData() {
      if (!this.getWpsData) return;
      return this.getWpsData();
    },
    wps_wordId() {
      return "wps_word" + generateId();
    },
    currentWpsFile() {
      return this.wpsList[0]
    }
  },
  methods: {
    creatWpsSdk() {
      // //创建 script 元素
      // const script = document.createElement('script');
      // script.src = '/wpsOffice/web-office-sdk-solution-v2.0.5.umd.js'; // 指定脚本文件的路径
      // script.id = 'WPSSdk'
      // script.async = true; // 如果需要的话，设置脚本异步加载
      // // 将 script 元素添加到 shadow root
      // document.body.appendChild(script);
    },
    setWpsHeight() {
      this.$nextTick(() => {
        // 使用closest函数查找最近的祖先元素，该元素具有指定的类名
        const parentClassName = '.el-scrollbar__view';
        if (!this.$refs.wps_word) return;
        var closestParent = this.$refs.wps_word.closest(parentClassName);
        if (closestParent === null) return;
        // 获取父元素的高度
        const wpsClientHeight = closestParent.clientHeight;
        if (this.$refs.wps_word.closest('.el-form-item') === null) return;
        let styleText = (this.$refs.wps_word.closest('.el-form-item') as HTMLElement).getAttribute('style');

        (this.$refs.wps_word.closest('.el-form-item') as HTMLElement).setAttribute('style', this.updateCssVariableValue(styleText, 'item-height', `${wpsClientHeight || 100}px`));
      })
    },
    updateCssVariableValue(cssString, variableName, newValue) {
      // 创建一个正则表达式来匹配CSS变量及其值
      // 注意：这里假设变量名不包含特殊字符，且值的格式是标准的（如数字+单位）
      const variableRegex = new RegExp(`(--${variableName.trim()}-variable:\\s*)(\\d+(?:px|em|rem|%|vh|vw|vmin|vmax|ch|ex|rem|pt|pc|cm|mm|in|q|s|ms|Hz|kHz|dpi|dpcm|dppx|deg|grad|rad|turn|s|ms|Hz|kHz|dpi))`, 'g');
      // 使用正则表达式替换CSS变量的值
      const updatedString = cssString.replace(variableRegex, `$1${newValue}`);
      return updatedString;
    },
    async initWpsSdk(id, fileType) {
      if (document.querySelector('#WPSSdk') == null) {
        await this.creatWpsSdk()
      }
      this.setWpsHeight();
      if (this.timeClear) {
        clearInterval(this.timeClear)
        this.timeClear = null
      }
      if (this.instance) {
        await this.instance.destroy()
      }
      this.instance = undefined;
      this.currentId = id;
      this.$emit("input", id);
      let type = 'edit';
      if (this.config.disabled) {
        type = 'preview';
      }
      getWpsUrl(id, type == 'edit' ? EventType.edit : EventType.preview, fileType && {type: fileType}).then(async (res) => {
        this.$nextTick(async () => {
          let sdkUrl = ''
          if (res.data.link) {
            sdkUrl = res.data.link;
          }
          this.$emit("input", sdkUrl);
          this.instance = await new WebOfficeSDK({
            mode: 'nomal',
            mount: this.$refs.wps_word,
            url: sdkUrl, // 文字自定义配置
            wordOptions: {
              isShowDocMap: false, // 是否开启目录功能，默认开启
              mobile: {
                isOpenIntoEdit: false, // （Mobile）要有编辑权限，移动端打开时是否进入编辑
              }
            },
            // 自定义的命令栏
            commandBars: [
              {
                // 命令栏的 ID
                cmbId: "FloatQuickHelp", // 右下角帮助（金小獴）
                // 命令栏的属性设置
                attributes: {
                  // 隐藏命令栏
                  visible: false, // 隐藏组件
                  // 禁用命令栏（组件显示但不响应点击事件）
                  enable: false, // 禁用组件（组件显示但不响应点击事件）
                },
              },
            ],
          })
          if (this.instance) {
          //   this.instance.ApiEvent.AddApiEventListener(
          //     "fileOpen",
          //     (data) => {
          //       console.log("fileOpen: ", data);
          //       this.setWpsHeight();
          //       this.setWpsFunction();
          //     }
          //   );
            this.instance.ApiEvent.AddApiEventListener("WindowSelectionChange", (data) => {
              this.wpsGetRangeText()
            });
          }
           window[this.wps_wordId] = this.instance;
          // 开启限制编辑
          try {
            let _this = this
            await this.instance.advancedApiReady();
            this.timeClear = setInterval(function () {
              if(!_this.$refs.wps_word){
                clearInterval(_this.timeClear)
                return
              }

              _this.setWpsHeight();
              let officeIframe = _this.$refs.wps_word.getElementsByClassName("web-office-iframe")[0];
              // 设置 SDK 的 iframe 高度
              officeIframe && (officeIframe.style.width = 99 + "%") && (officeIframe.style.height = (_this.$refs.wps_word.clientHeight - 10) + 'px');
            }, 500);
            this.setWpsFunction();
            this.$emit("setWpsId", this.wps_wordId)
            const app = this.instance.Application;
            // 分页/连页模式切换
            // 为 true 表示切换成功，为 false 表示切换失败
            await app.ActiveDocument.SwitchTypoMode(false);
            if (this.config.disabled) {
              const moreMenus = await app.CommandBars('MoreMenus');
              moreMenus.Visible = false;
              // 设置为只读 暂时使用当前方法来解决Protect方法导致的问题, 后期测试没问题可删除注释掉的方法
              await app.ActiveDocument.SetReadOnly({
                Value: true,
              });
            } else {
              // await app.ActiveDocument.Unprotect('zhhh-admin');
              await app.ActiveDocument.SetReadOnly({
                Value: false,
              });
            }
            // 定义右键菜单
            if (this.config.morePermissions.wpsControlsMenu && this.config.morePermissions.wpsControlsMenu.length) {
              const controls = await app.CommandBars('TextMenu').Controls;
              // 新增按钮型定制元素 1 是可控按钮 10 是可控的下拉框
              this.config.morePermissions.wpsControlsMenu.forEach(async item => {
                const controlButton = await controls.Add(1);
                controlButton.Caption = item.name;
                controlButton.Picture = item.icon;
                controlButton.OnAction = () => item.callBack()
              });
            }
            // 将当前文档的编辑状态切换成修订模式
            app.ActiveDocument.TrackRevisions = true;
          } catch (error) {
            console.log(error);

          }
        });


      })

    },
    setWpsFunction() {
      this.wpsFunction.wpsAddPicture = this.wpsAddPicture;
      this.wpsFunction.wpsSaveDoc = this.wpsSaveDoc;
      this.wpsFunction.wpsGetRangeText = this.wpsGetRangeText;
      this.wpsFunction.wpsInsertText = this.wpsInsertText;
      this.wpsFunction.wpsReplaceText = this.wpsReplaceText;
      this.wpsFunction.wpsActiveDocumentRangeStart =
        this.wpsActiveDocumentRangeStart;
      this.wpsFunction.wpsActiveDocumentRangeEnd = this.wpsActiveDocumentRangeEnd;
      this.wpsFunction.wpsActiveDocumentRangeText =
        this.wpsActiveDocumentRangeText;
      this.wpsFunction.wpsActiveDocumentRangeCount = this.wpsActiveDocumentRangeCount;
      this.wpsFunction.wpsActiveDocumentSetRange = this.wpsActiveDocumentSetRange;
      this.wpsFunction.wpsGetDocumentParagraphsItem = this.wpsGetDocumentParagraphsItem;
      this.wpsFunction.fileUpload = this.fileUpload;
      this.wpsFunction.wpsSetDocumentBgColor = this.wpsSetDocumentBgColor;
      this.wpsFunction.getWpsFileUrl = this.getWpsFileUrl;
      this.wpsFunction.wpsDocumentTextCount = this.wpsDocumentTextCount;
      this.wpsFunction.wpsActiveDocumentRevisionsCount = this.wpsActiveDocumentRevisionsCount;
      this.wpsFunction.wpsActiveDocumentRevisionsAcceptAll = this.wpsActiveDocumentRevisionsAcceptAll;
      this.wpsFunction.wpsDocumentTrackRevisions = this.wpsDocumentTrackRevisions;
      this.wpsFunction.wpsDocumentshowRevisions = this.wpsDocumentshowRevisions;
      this.wpsFunction.wpsActiveDocumentActiveWindowSelectionPos = this.wpsActiveDocumentActiveWindowSelectionPos;
      this.wpsFunction.wdNumberOfPagesInDocument = this.wdNumberOfPagesInDocument;

      this.wpsFunction.wpsAllRangeText = this.wpsAllRangeText;
      this.wpsFunction.wpsAcceptAll = this.wpsAcceptAll;
      this.wpsFunction.example = this.example;
      this.wpsFunction.getPages = this.getPages;
      this.wpsFunction.saveDocHandle = () => {
        this.instance.save();
      };
      window[this.wps_wordId].functionObj = this.wpsFunction;
      this.example()

    },
    handleClick(tab, event) {
      this.initWpsSdk(this.wpsList[tab].id, this.wpsList[tab].fileType)
    },

    async fileUpload(param, obj) {
      try {
        let file = param.file;
        let formData = new FormData();
        formData.append("file", file);
        // fileUpload("oaword", formData).then(async (res) => {
        //   this.instance = undefined;
        //   if (res.code === 200) {
        //     let id = res.data.id;
        //     this.getWpsFileUrl(id);
        //   } else {
        //     this.$message({
        //       message: res.msg,
        //       type: "warning",
        //     });
        //   }
        // });
      } catch (e) { }
    },
    async getPages() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取总页数
      const totalPages = await app.ActiveDocument.Range.Information(app.Enum.WdInformation.wdNumberOfPagesInDocument);
      console.log(totalPages, '页数');

      return totalPages
    },
    async wpsAcceptAll() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取修订对象
      const revisions = await app.ActiveDocument.Revisions;
      // 接受对指定文档的所有修订
      await revisions.AcceptAll();
    },
    async example() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 对文档窗口大小进行调整后，是否缩放视图以适应文档窗口的尺寸
      app.ActiveDocument.ActiveWindow && (app.ActiveDocument.ActiveWindow.View.Zoom.Percentage = 100);
      // app.ActiveDocument.ActiveWindow.View.Zoom.PageFit = 0;
    },
    async wpsGetEidtRevisions() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取修订对象
      const revisions = await app.ActiveDocument.Revisions;
      // 获取全文修订内容
      const revisionData = await revisions.Json();
      return revisionData;
    },
    // 获取所有文本
    async wpsAllRangeText() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 返回一个 Range 对象
      const range = await app.ActiveDocument.Content;
      // 获取 range 内文本内容信息  
      const text = await range.Text;
      return text;
    },
    
    // 更新wps文件版本
    getFileHandlingAddNewFile(docFileId, fileId) {
      // return fileHandlingAddNewFile({
      //   fileId,
      //   wpsFileId: docFileId,
      // });
    },
    // 获取wps文件url
    getWpsFileUrl(fileId, type) {
      this.$emit("input", fileId);
      getWpsUrl(fileId, type == 'edit' ? EventType.edit : EventType.preview).then(async (res) => {
        if (res.code === 200) {
          const link = res.data.link;
          this.wpsData.data.link = link;
          sessionStorage.setItem("wpsId", fileId);
          // this.$eventBus.$emit("upDocFileIdEventBus", fileId);
        } else {
          this.$message({
            message: res.msg,
            type: "warning",
          });
        }
      });
    },
    // wps插入图片
    async wpsAddPicture(pictureUrl, BookName) {
      try {
        await this.instance.advancedApiReady();
        const app = this.instance.Application;

        // 获取图形对象
        const shapes = await app.ActiveDocument.Shapes;
        // const InlineShapes = await app.ActiveDocument.InlineShapes;
        // 插入非嵌入式图片
        await shapes.AddPicture({
          FileName: pictureUrl, // 图片地址
          LinkToFile: false,
          SaveWithDocument: false,
          Left: 10, // 图片距离左边位置
          Top: 10, // 图片距离顶部位置
          Width: 120, // 图片宽度
          Height: 120, // 图片高度
        });
        // 设置文字环绕模式为'衬于文字上方'
        const shape = await app.ActiveDocument.Shapes.Item(1);
        shape.ZOrder(app.Enum.ZOrderCmd.bringInFrontOfText); // bringInFrontOfText
      } catch (e) {
        console.error(e)
      }
    },
    // 保存当前文档内容
    async wpsSaveDoc() {
      try {
        await this.instance.advancedApiReady();
        const app = this.instance.Application;
        // 保存文件的改动
        await app.ActiveDocument.Save();
        return true
      } catch (error) {
        console.error('save error', error)
        return false
      }
    },
    // 获取选区内文本内容
    async wpsGetRangeText() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 选区对象
      const selection = await app.ActiveDocument.ActiveWindow.Selection;
      // Range 对象
      const range = await selection.Range;
      // 获取选中文本
      const text = await range.Text;

      this.getGlobalDsv().wpsWordRangeText({
        wps_wordId: this.wps_wordId,
        componentId: this.config.name, // 组件唯一值
      }, text)

      return text;
    },
    // 插入文本
    async wpsInsertText(text) {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 选区后插入文本
      await app.ActiveDocument.ActiveWindow.Selection.InsertAfter(text);
    },
    // 修改、替换文本
    async wpsReplaceText(arr) {
      // arr: [{key,value}]
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      const isSuccess = await app.ActiveDocument.ReplaceText(arr);
    },
    // 获取区域开始位置
    async wpsActiveDocumentRangeStart() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取选中区域
      const range = await app.ActiveDocument.Range(0, 10);
      // 获取选中文本的起点位置
      const start = await range.Start;
    },
    // 获取区域结束位置
    async wpsActiveDocumentRangeEnd() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取选中区域
      const range = await app.ActiveDocument.Range(5, 100);
      // 获取选中文本的终点位置
      const end = await range.End;
    },
    // 获取文档整体结束位置
    async wpsDocumentTextCount() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取全文范围
      const ranges = await app.ActiveDocument.GetDocumentRange();
      const count = await ranges.End;
      return count - 9;
    },
    // 获取文章总段落
    async wpsActiveDocumentRangeCount() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      const textEndCount = await this.wpsDocumentTextCount();
      // 获取所有段落
      const paragraphs = await app.ActiveDocument.Range(0, textEndCount).Paragraphs;
      // 获取段落总数量
      const count = await paragraphs.Count;
      const paragraphArr = [];
      if (count > 0) {
        for (var i = 1; i <= count; i++) {
          // 获取每个段落
          const paragraph = paragraphs.Item(i);
          const textRang = await paragraph.Range;
          const start = await textRang.Start;
          const end = await textRang.End;
          const txt = await textRang.Text;
          paragraphArr.push({
            txt: txt.toString().replace("\r", ""),
            start,
            end,
            floor: i,
          });
        }
      }
      return paragraphArr;
    },
    // 获取对应段落并返回段落文案
    async wpsGetDocumentParagraphsItem(i) {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      const textEndCount = await this.wpsDocumentTextCount();
      // 获取所有段落
      const paragraphs = await app.ActiveDocument.Range(0, textEndCount).Paragraphs;
      const paragraph = paragraphs.Item(i);
      const textRang = await paragraph.Range;
      const txt = await textRang.Text;
      return txt;
    },
    // 设置选中范围
    async wpsActiveDocumentSetRange(start = 0, end = 0) {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取选中区域Range  两个参数没效果？
      const range = await app.ActiveDocument.Range(0, 1);
      // 设置区域范围 起始位置 不包括结束位置
      await range.SetRange(start, end);
    },
    // 设置选区高亮
    async wpsSetDocumentBgColor(start = 0, end = 0, color = "#FFE1AC") {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 字体对象
      const font = await app.ActiveDocument.Range(start, end).Font;
      // 设置选定文字的字体颜色
      font.HighLight = color;
    },
    // 通过 Range 选定区域，从而获取和设置到具体的文本内容信息
    async wpsActiveDocumentRangeText(
      start = 0,
      end = 0,
      replaceText = undefined
    ) {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取选中区域 不包括结束位置
      const range = await app.ActiveDocument.Range(start, end);
      // 获取文本
      // const text = await range.Text;

      // 设置文本
      if (replaceText !== undefined) {
        range.Text = replaceText;
      }
    },
    // 获取全文修订数量
    async wpsActiveDocumentRevisionsCount() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取修订对象
      const revisions = await app.ActiveDocument.Revisions;
      // 获取全文修订数量
      const count = await revisions.Count;
      return count;
    },
    // 接受文档所有修订
    async wpsActiveDocumentRevisionsAcceptAll() {
      try {
        await this.instance.advancedApiReady();
        const app = this.instance.Application;
        // 获取修订对象
        const revisions = await app.ActiveDocument.Revisions;
        // 接受对指定文档的所有修订
        await revisions.AcceptAll();
        return true
      } catch (error) {
        return false
      }
    },
    // 设置修订模式开关
    async wpsDocumentTrackRevisions(isEdit = true) {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      app.ActiveDocument.TrackRevisions = isEdit;
    },
    // 设置修订的 标记状态
    async wpsDocumentshowRevisions(type = 2) {
      await this.instance.ready();
      const app = this.instance.Application;
      // 获取节对象
      const View = await app.ActiveDocument.ActiveWindow.View
      switch (type) {
        case 1:
          // 设置修订状态为最终状态
          View.RevisionsFilter.view = 0
          // 设置修订状态为 显示标记的最终状态
          View.ShowRevisionsAndComments = true
          break;
        case 2:
          // 设置修订状态为最终状态
          View.RevisionsFilter.view = 0
          // 设置修订状态为 最终状态
          View.ShowRevisionsAndComments = false
          break;
        case 3:
          // 设置修订状态为原始状态
          View.RevisionsFilter.view = 1
          // 设置修订状态为 显示标记的原始状态
          View.ShowRevisionsAndComments = true
          break;
        case 4:
          // 设置修订状态为原始状态
          View.RevisionsFilter.view = 1
          // 设置修订状态为 原始状态
          View.ShowRevisionsAndComments = false
          break;
        default:
          break;
      }
    },
    // 获取位置
    async wpsActiveDocumentActiveWindowSelectionPos() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 选区对象
      const selection = await app.ActiveDocument.ActiveWindow.Selection;
      // Range 对象
      const range = await selection.Range;
      // 获取选中文本的起点位置
      const start = await range.Start;
      const end = await range.End + 1;
      console.log(start);
      console.log(end);
      return {
        start,
        end
      }
    },
    // 获取当前第几页
    async wdNumberOfPagesInDocument() {
      await this.instance.advancedApiReady();
      const app = this.instance.Application;
      // 获取总页数
      const currentPage = await app.ActiveDocument.ActiveWindow.Selection.Information(app.Enum.WdInformation.wdActiveEndPageNumber);
      console.log(currentPage);
    }
  },
};
</script>

<style lang="scss" scoped>
.form-detail {
  display: flex;
  align-items: center;
  flex-direction: column;
  background: #eeeeef;
  padding-right: 0;
  height: 100%;
  overflow: hidden;
  width: 100%;

  .demo-tabs {
    width: 100%;
    text-align: left;
    background-color: #d8d8d8;

    :deep(.el-tabs__header) {
      margin: 0 !important;
    }

    :deep(.el-tabs__nav) {
      padding: 0 !important
    }

    :deep(.is-active) {
      background: #eeeeee
    }
  }
}

.office-container {
  width: 100%;
  background: #ffffff;

  .el-scrollbar__view {
    height: 100%;

    .form-wps {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
